package com.yuyou.fn.portal.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.ClassLecture;
import com.yuyou.fn.portal.entity.OuterShoppingcart;
import com.yuyou.fn.portal.mapper.OuterShoppingcartMapper;
import com.yuyou.fn.portal.service.IOuterCourseClassService;
import com.yuyou.fn.portal.service.IOuterShoppingcartService;
import com.yuyou.fn.portal.vo.ShoppingCartDetailVo;
import org.apache.commons.lang3.Validate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * OuterShoppingcart 表数据服务层接口实现类
 */
@Service
public class OuterShoppingcartServiceImpl extends SuperServiceImpl<OuterShoppingcartMapper, OuterShoppingcart, Long> implements IOuterShoppingcartService {

    @Resource
    private IOuterCourseClassService outerCourseClassService;

    @Override
    @Transactional
    public void addToShoppingCartByQrCode(List<Long> classIds, Long userId, Long counselorId) {
        Validate.notNull(classIds,"Required classIds");
        Validate.notNull(userId,"Required userId");
        List<OuterShoppingcart> shoppingCartDetailVos=this.findOuterShoppingcart(userId);
        Map<Long, OuterShoppingcart> shoppingCartDetailVoMap = BeanUtils.toMap(shoppingCartDetailVos, "classId");

        if (Utils.checkListNotEmpty(classIds)){
            List<Long> outerShoppingcartIds=new ArrayList<>(shoppingCartDetailVoMap.size());
            List<OuterShoppingcart> outerShoppingcartList=new ArrayList<>(classIds.size());
            for (Long classId:classIds){
                if (shoppingCartDetailVoMap.containsKey(classId)){
                    outerShoppingcartIds.add(shoppingCartDetailVoMap.get(classId).getOuterShoppingcartId());
                }
                OuterShoppingcart outerShoppingcart=new OuterShoppingcart();
                outerShoppingcart.setClassId(classId);
                outerShoppingcart.setUserId(userId);
                outerShoppingcart.setCreateTime(TimeUtils.now());
                outerShoppingcart.setUpdateTime(TimeUtils.now());
                outerShoppingcart.setCounselorId(counselorId);
                outerShoppingcartList.add(outerShoppingcart);
            }
            if (outerShoppingcartIds.size()>0){
                this.deleteBatchIds(outerShoppingcartIds);
            }
            this.insertBatch(outerShoppingcartList);
        }

    }

    @Override
    public OuterShoppingcart addToShoppingCart(Long classId, Long userId,Long counselorId) {
        Validate.notNull(classId,"Required classId");
        Validate.notNull(userId,"Required userId");
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andEqualTo("classId",classId);
        if(this.countByExample(example)>0){
            throw new BusException("购物车已存在相同内容");
        }
        OuterShoppingcart outerShoppingcart=new OuterShoppingcart();
        outerShoppingcart.setClassId(classId);
        outerShoppingcart.setUserId(userId);
        outerShoppingcart.setCreateTime(TimeUtils.now());
        outerShoppingcart.setUpdateTime(TimeUtils.now());
        outerShoppingcart.setCounselorId(counselorId);
        this.insertSelective(outerShoppingcart);
        return outerShoppingcart ;
    }

    @Override
    public void deleteShoppingCart(List<Long> outerShoppingCartIds,Long userId) {
        if(outerShoppingCartIds == null || userId == null){
            throw new NullPointerException();
        }
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andIn("outerShoppingcartId",outerShoppingCartIds);
        this.deleteByExample(example);
    }


    public int  toMini(Date date){
        return (int)( date.getTime()/1000/60  - 24720000l/*2017-01-01*/ ) ;
    }
    private BitSet toBitSet(List<ClassLecture> classLectureList, SimpleDateFormat dateSdf, SimpleDateFormat timeSdf)  {
        BitSet bitSet = new BitSet();
        try{
            for(ClassLecture classTime : classLectureList ){
                if (classTime.getClassDate()!=null){
                    String date = dateSdf.format(classTime.getClassDate());
                    Date start = timeSdf.parse(date +" "+ classTime.getStartTime()) ;
                    Date end = timeSdf.parse(date + " " + classTime.getEndTime()) ;
                    bitSet.set(toMini(start),toMini(end) ,true );
                }
            }
        }catch (ParseException e){
            throw  new BusException("对比课程时间段发生异常");
        }

        return bitSet;
    }


    @Override
    public Long countNumByUserId(Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        example.createCriteria().andEqualTo("userId",userId);

        return this.countByExample(example);
    }

    @Override
    public List<ShoppingCartDetailVo> findShoppingCartList(Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        example.createCriteria().andEqualTo("userId",userId);
       // example.selectProperties("classId");
        List<OuterShoppingcart> list=this.findListByExample(example);
        List<ShoppingCartDetailVo> shoppingCartDetailVoList = toShoppingCartDetailVo(list);

        return shoppingCartDetailVoList;
    }

    @Override
    public List<OuterShoppingcart> findOuterShoppingcart(Long userId) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        example.createCriteria().andEqualTo("userId",userId);
        // example.selectProperties("classId");
        List<OuterShoppingcart> list=this.findListByExample(example);
        return list;
    }

    private List<ShoppingCartDetailVo> toShoppingCartDetailVo(List<OuterShoppingcart> list) {
        List<ShoppingCartDetailVo> shoppingCartDetailVoList=new ArrayList<ShoppingCartDetailVo>();
        for (OuterShoppingcart outerShoppingcart:list){
            ShoppingCartDetailVo shoppingCartDetailVo=new ShoppingCartDetailVo();
            shoppingCartDetailVo.setOuterShoppingCartId(outerShoppingcart.getOuterShoppingcartId());
            shoppingCartDetailVo.setCourseClassResultVo(outerCourseClassService.findSimpleCourseClassByClassId(outerShoppingcart.getClassId()));
            shoppingCartDetailVoList.add(shoppingCartDetailVo);
        }
        return shoppingCartDetailVoList;
    }

    @Override
    public List<ShoppingCartDetailVo> findShoppingCartList(List<Long> outerShoppingCartIds) {
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        example.createCriteria().andIn("outerShoppingcartId",outerShoppingCartIds );
        // example.selectProperties("classId");
        List<OuterShoppingcart> list=this.findListByExample(example);
        List<ShoppingCartDetailVo> shoppingCartDetailVoList = toShoppingCartDetailVo(list);
        return shoppingCartDetailVoList;
    }

    @Override
    public void deleteByUserIdAndClassId(Long userId, Long classId) {
        if(userId == null || classId == null ){
            throw new NullPointerException();
        }
        Example<OuterShoppingcart> example=OuterShoppingcart.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andEqualTo("classId",classId);
        deleteByExample(example);
    }


    @Override
    public OuterShoppingcart findOneRecent(Long userId) {
        Example<OuterShoppingcart> example = OuterShoppingcart.createExample();
        example.createCriteria().andEqualTo("userId",userId);
        example.orderBy("createTime").desc();
        return findOneByExample(example);

    }
}
